Skip to content

[libc++] Document how __tree is laid out and how we iterate through it #152453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

philnik777
Copy link
Contributor

No description provided.

@philnik777 philnik777 requested a review from a team as a code owner August 7, 2025 08:32
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Aug 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 7, 2025

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/152453.diff

1 Files Affected:

  • (modified) libcxx/include/__tree (+26)
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 3dd5ae585e1db..80ad56e5e7805 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -49,6 +49,27 @@
 _LIBCPP_PUSH_MACROS
 #include <__undef_macros>
 
+// __tree is a red-black-tree implementation used for the associative containers (i.e. (multi)map/set). To allow for
+// constant time lookup, it stores
+// - (1) a pointer to the node with the smallest (i.e. leftmost) element, namely __begin_node_
+// - (2) the number of nodes in the tree, namely __size_
+//
+// A pointer to the root of the tree is stored in the __end_node_.
+// A tree looks like this in memory:
+//
+//      __end_node_
+//           |
+//          root
+//         /    \
+//       l1       r1
+//      /  \     /  \
+//    ...  ... ...  ...
+//
+// All nodes except __end_node_ have a __left_ and __right_ pointer as well as a __parent_ pointer.
+// __end_node_ only contains a __left_ pointer, which point to the root of the tree.
+// This layout allows for iteration through the tree without a need for special handling of the end node. See
+// __tree_next_iter and __tree_prev_iter for more details.
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp, class _Compare, class _Allocator>
@@ -183,6 +204,11 @@ _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
   return __x->__parent_unsafe();
 }
 
+// __tree_next_iter and __tree_prev_iter implement iteration through the tree. The order is as follows:
+// left sub-tree -> node -> right sub-tree. When the right-most node of a sub-tree is reached, we walk up the tree until
+// we find a node where we were in the left sub-tree. We are _always_ in a left sub-tree, since the __end_node_ points
+// to the actual root of the tree through a __left_ pointer. incrementing the end() pointer is UB, so we can assume that
+// never happens.
 template <class _EndNodePtr, class _NodePtr>
 inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
   _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the documentation, LGTM with minor tweaks!

@philnik777 philnik777 force-pushed the tree_document_layout branch from 10ed466 to e197f6f Compare August 12, 2025 07:46
@philnik777 philnik777 force-pushed the tree_document_layout branch from e197f6f to 67259fd Compare August 13, 2025 08:25
@ldionne ldionne changed the title [libc++] Document how __tree is layed out and how we iterate through it [libc++] Document how __tree is laid out and how we iterate through it Aug 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants